package com.esd.device.controller;

import com.esd.common.pojo.R;
import com.esd.device.entity.vo.DeviceVo;
import com.esd.device.task.DeviceConstants;
import com.esd.device.utils.NumberUtils;
import com.esd.device.utils.Tcp_Utils_Nio;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
@RestController
@RequestMapping("/temAndHum")
public class TemAndHumController extends BaseOperationController {

    @Autowired
    private Tcp_Utils_Nio tcp_utils_nio ;

    @PostMapping("/setTime")
    public R setTime(
            @RequestBody DeviceVo deviceVo
    ){
        String hexString = NumberUtils.longToHexString(Long.parseLong(deviceVo.getStationId()), 8);
        String commandStr = hexString + " " + "00 10 00 3C 00 07 0E";
        LocalDateTime now = LocalDateTime.now();

        int year = now.getYear()%2000 ;
        if (year< 10){
            commandStr = commandStr + " 00 0" + year ;
        }else if (year<=99){
            commandStr = commandStr + " 00 " + year ;
        }

        int month = now.getMonthValue();
        if (month< 10){
            commandStr = commandStr + " 00 0" + month ;
        }else {
            commandStr = commandStr + " 00 " + month ;
        }

        int day = now.getDayOfMonth();
        if (day< 10){
            commandStr = commandStr + " 00 0" + day ;
        }else {
            commandStr = commandStr + " 00 " + day ;
        }

        int hour = now.getHour();
        if (hour< 10){
            commandStr = commandStr + " 00 0" + hour ;
        }else {
            commandStr = commandStr + " 00 " + hour ;
        }

        int minute = now.getMinute();
        if (minute< 10){
            commandStr = commandStr + " 00 0" + minute ;
        }else {
            commandStr = commandStr + " 00 " + minute ;
        }

        int dayOfWeek = now.getDayOfWeek().getValue();
        commandStr = commandStr + " 00 0" + dayOfWeek ;

        int second = now.getSecond();
        if (second< 10){
            commandStr = commandStr + " 00 0" + second ;
        }else {
            commandStr = commandStr + " 00 " + second ;
        }
        ReentrantLock reentrantLock = DeviceConstants.LockMap.get(deviceVo.getServerIp());
        reentrantLock.lock();
        String resultStr = "";
        try {
            resultStr = tcp_utils_nio.sendCommand1(deviceVo.getServerIp(), deviceVo.getServerPort(), commandStr, 300);
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        if (resultStr.equals("error")) {
            return  R.error( "可能网关停机了，请检查");
        } else if (resultStr.isEmpty()) {
            return  R.error( "无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
        } else {
            return  R.ok("校正时间成功！！");
        }
    }

    @PostMapping("getTemUpperAndLower")
    public R getTemUpperAndLower(
            @RequestBody DeviceVo deviceVo
    ) {
        String hexString = NumberUtils.longToHexString(Long.parseLong(deviceVo.getStationId()), 8);
        String commandStr = hexString + " " + "00 03 00 9B 00 02";
        ReentrantLock reentrantLock = DeviceConstants.LockMap.get(deviceVo.getServerIp());
        reentrantLock.lock();
        String resultStr = "";
        try {
            resultStr = tcp_utils_nio.sendCommand1(deviceVo.getServerIp(), deviceVo.getServerPort(), commandStr, 300);
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        if (resultStr.equals("error")) {
            return  R.error( "可能网关停机了，请检查");
        } else if (resultStr.isEmpty()) {
            return  R.error( "无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
        } else {
            String[] ss = resultStr.substring(21).split(" ");
            BigDecimal temUpper = new BigDecimal(NumberUtils.hexToInt(ss[0] + ss[1])).divide(new BigDecimal(10));
            BigDecimal temLower = new BigDecimal(NumberUtils.hexToInt(ss[2] + ss[3])).divide(new BigDecimal(10));
            Map<String , BigDecimal> map = new HashMap<>();
            map.put("temUpper", temUpper) ;
            map.put("temLower", temLower) ;
            return  R.ok(map);
        }
    }

    @PostMapping("temClick/{status}")
    public R temClick(
            @RequestBody DeviceVo deviceVo ,
            @PathVariable String status
    ){
        String hexString = NumberUtils.longToHexString(Long.parseLong(deviceVo.getStationId()), 8);
        String commandStr = hexString + " " + "00 06 00 9F 00 " + status;
        ReentrantLock reentrantLock = DeviceConstants.LockMap.get(deviceVo.getServerIp());
        reentrantLock.lock();
        String resultStr = "";
        try {
            resultStr = tcp_utils_nio.sendCommand1(deviceVo.getServerIp(), deviceVo.getServerPort(), commandStr, 300);
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        if (resultStr.equals("error")) {
            return  R.error( "可能网关停机了，请检查");
        } else if (resultStr.isEmpty()) {
            return  R.error( "无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
        } else {
            return  R.ok("温度报警开关" + (status.equals("01")?"开启":"关闭") + "成功！！");
        }
    }

    @PostMapping("humiClick/{status}")
    public R humiClick(
            @RequestBody DeviceVo deviceVo ,
            @PathVariable String status
    ){
        String hexString = NumberUtils.longToHexString(Long.parseLong(deviceVo.getStationId()), 8);
        String commandStr = hexString + " " + "00 06 00 A0 00 " + status;
        ReentrantLock reentrantLock = DeviceConstants.LockMap.get(deviceVo.getServerIp());
        reentrantLock.lock();
        String resultStr = "";
        try {
            resultStr = tcp_utils_nio.sendCommand1(deviceVo.getServerIp(), deviceVo.getServerPort(), commandStr, 300);
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        if (resultStr.equals("error")) {
            return  R.error( "可能网关停机了，请检查");
        } else if (resultStr.isEmpty()) {
            return  R.error( "无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
        } else {
            return  R.ok("湿度报警开关" + (status.equals("01")?"开启":"关闭") + "成功！！");
        }
    }

    @PostMapping("getHumiUpperAndLower")
    public R getHumiUpperAndLower(
            @RequestBody DeviceVo deviceVo
    ) {
        String hexString = NumberUtils.longToHexString(Long.parseLong(deviceVo.getStationId()), 8);
        String commandStr = hexString + " " + "00 03 00 9D 00 02";
        ReentrantLock reentrantLock = DeviceConstants.LockMap.get(deviceVo.getServerIp());
        reentrantLock.lock();
        String resultStr = "";
        try {
            resultStr = tcp_utils_nio.sendCommand1(deviceVo.getServerIp(), deviceVo.getServerPort(), commandStr, 300);
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        if (resultStr.equals("error")) {
            return  R.error( "可能网关停机了，请检查");
        } else if (resultStr.isEmpty()) {
            return  R.error( "无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
        } else {
            String[] ss = resultStr.substring(21).split(" ");
            BigDecimal humiUpper = new BigDecimal(NumberUtils.hexToInt(ss[0] + ss[1])).divide(new BigDecimal(10));
            BigDecimal humiLower = new BigDecimal(NumberUtils.hexToInt(ss[2] + ss[3])).divide(new BigDecimal(10));
            Map<String , BigDecimal> map = new HashMap<>();
            map.put("humiUpper", humiUpper) ;
            map.put("humiLower", humiLower) ;
            return  R.ok(map);
        }
    }

    @PostMapping("setTemUpperAndLower/{scale}")
    public R setTemUpperAndLower(
            @RequestBody DeviceVo deviceVo,
            @PathVariable String scale
            ){
        String hexString = NumberUtils.longToHexString(Long.parseLong(deviceVo.getStationId()), 8);
        String[] ss = scale.split("-");
        String s1, s2;
        s1 = NumberUtils.intToHexString(Integer.parseInt(ss[0]), 4);
        s2 = NumberUtils.intToHexString(Integer.parseInt(ss[1]), 4);

        String commandStr = hexString + " " + "00 10 00 9B 00 02 02 " + s2 + " " + s1;
        ReentrantLock reentrantLock = DeviceConstants.LockMap.get(deviceVo.getServerIp());
        reentrantLock.lock();
        String resultStr = "";
        try {
            resultStr = tcp_utils_nio.sendCommand1(deviceVo.getServerIp(), deviceVo.getServerPort(), commandStr, 300);
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        if (resultStr.equals("error")) {
            return  R.error( "可能网关停机了，请检查");
        } else if (resultStr.isEmpty()) {
            return  R.error( "无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
        } else {
            return  R.ok("温度报警上下线设置成功！！");
        }
    }

    @PostMapping("setHumiUpperAndLower/{scale}")
    public R setHumiUpperAndLower(
            @RequestBody DeviceVo deviceVo,
            @PathVariable String scale
    ){
        String hexString = NumberUtils.longToHexString(Long.parseLong(deviceVo.getStationId()), 8);
        String[] ss = scale.split("-");
        String s1 = NumberUtils.intToHexString(Integer.parseInt(ss[0]), 4);
        String s2 = NumberUtils.intToHexString(Integer.parseInt(ss[1]), 4);
        String commandStr = hexString + " " + "00 10 00 9D 00 02 02 " + s2 + " " + s1;
        ReentrantLock reentrantLock = DeviceConstants.LockMap.get(deviceVo.getServerIp());
        reentrantLock.lock();
        String resultStr = "";
        try {
            resultStr = tcp_utils_nio.sendCommand1(deviceVo.getServerIp(), deviceVo.getServerPort(), commandStr, 300);
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        if (resultStr.equals("error")) {
            return  R.error( "可能网关停机了，请检查");
        } else if (resultStr.isEmpty()) {
            return  R.error( "无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
        } else {
            return  R.ok("湿度报警上下线设置成功！！");
        }
    }

    @PostMapping("geTemDetail")
    public R geTemDetail(
            @RequestBody DeviceVo deviceVo
    ){
        String hexString = NumberUtils.longToHexString(Long.parseLong(deviceVo.getStationId()), 8);
        String commandStr1 = hexString + " 00 03 00 9B 00 04";
        String commandStr2 = hexString + " 00 03 00 0A 00 02" ;
        ReentrantLock reentrantLock = DeviceConstants.LockMap.get(deviceVo.getServerIp());
        reentrantLock.lock();
        String resultStr1 = "";
        try {
            resultStr1 = tcp_utils_nio.sendCommand1(deviceVo.getServerIp(), deviceVo.getServerPort(), commandStr1, 300);
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }

        reentrantLock.lock();
        String resultStr2 = "";
        try {
            resultStr2 = tcp_utils_nio.sendCommand1(deviceVo.getServerIp(), deviceVo.getServerPort(), commandStr2, 300);
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }

        if (resultStr1.equals("error")) {
            return  R.error( "可能网关停机了，请检查");
        } else if (resultStr1.isEmpty()) {
            return  R.error( "无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
        } else {
            String[] ss = resultStr2.substring(21).split(" ");
            Map<String, String> map = new HashMap<>();
            BigDecimal tem = new BigDecimal(NumberUtils.hexToInt(ss[0] + ss[1])).divide(new BigDecimal(10));
            String[] ss1 = resultStr1.substring(21).split(" ");
            BigDecimal temUpper = new BigDecimal(NumberUtils.hexToInt(ss1[0] + ss1[1])).divide(new BigDecimal(10));
            BigDecimal temLower = new BigDecimal(NumberUtils.hexToInt(ss1[2] + ss1[3])).divide(new BigDecimal(10));
            String temFlag;
            int result1 = tem.compareTo(temLower);
            int result2 = tem.compareTo(temUpper);
            if(result1<0 || result2>0){
                temFlag = "报警" ;
            }else {
                temFlag = "正常" ;
            }
            map.put("tem", "温度为: " + tem +"℃  状态为:  " + temFlag);

            BigDecimal humiUpper = new BigDecimal(NumberUtils.hexToInt(ss1[4] + ss1[5])).divide(new BigDecimal(10));
            BigDecimal humiLower = new BigDecimal(NumberUtils.hexToInt(ss1[6] + ss1[7])).divide(new BigDecimal(10));
            BigDecimal humi = new BigDecimal(NumberUtils.hexToInt(ss[2] + ss[3])).divide(new BigDecimal(10));

            String humiFlag;
            int result3 = humi.compareTo(humiLower);
            int result4 = humi.compareTo(humiUpper);
            if(result3<0 || result4>0){
                humiFlag = "报警" ;
            }else {
                humiFlag = "正常" ;
            }
            map.put("tem", "温度为: " + tem +"℃  状态为:  " + temFlag);
            map.put("humi", "湿度为: " + humi +"%  状态为:  " + humiFlag);
            return  R.ok(map);
        }
    }
}
